package com.shadowtorcher.stdisk.logic;

import com.shadowtorcher.soulknife.SoulKnifeDB;
import com.shadowtorcher.soulknife.exception.BeanConfigErrorException;
import com.shadowtorcher.stdisk.bean.LogicFileBean;
import com.shadowtorcher.stdisk.bean.PhysicsFileBean;
import com.shadowtorcher.stdisk.bean.UserBean;
import com.shadowtorcher.stdisk.util.FileTypePatternGenerator;
import com.shadowtorcher.stdisk.util.Tuple;

import java.sql.SQLException;
import java.util.*;
import java.util.regex.Pattern;

import static com.shadowtorcher.stdisk.util.FileTypePatternGenerator.getRegular;

public class FileLister {
    private static Map<UserBean, Tuple<String, List<LogicFileBean>>> cache = new HashMap<>();
    private UserBean user;

    public FileLister(UserBean user) {
        this.user = user;
    }

    public static long getFileSize(LogicFileBean logicFile) throws SQLException {
        try {
            return SoulKnifeDB.selectWhere("PhysicsFileID = ?", logicFile.getPhysicsFileID()).setClass(PhysicsFileBean.class).get(0).getFileSize();
        } catch (BeanConfigErrorException | NullPointerException e) {
            e.printStackTrace();
            return 0;
        }
    }

    public static long getFileSize(String logicFileID) throws SQLException {
        try {
            LogicFileBean logicFile = SoulKnifeDB.selectWhere("logicFileID = ?", logicFileID).setClass(LogicFileBean.class).get(0);
            return getFileSize(logicFile);
        } catch (BeanConfigErrorException | NullPointerException e) {
            e.printStackTrace();
            return 0;
        }
    }

    public List<LogicFileBean> listAllFile(String path) throws SQLException {
        List<LogicFileBean> list = new ArrayList<>();
        try {
            List<LogicFileBean> files = SoulKnifeDB.selectWhere("UserID = ? and LogicPath like ?", user.getUserID(), path + "%").setClass(LogicFileBean.class);
            list = list(files, path);
        } catch (BeanConfigErrorException e) {
            e.printStackTrace();
        }
        return list;
    }

    public List<LogicFileBean> listRecentFile() throws SQLException {
        List<LogicFileBean> list = new ArrayList<>();
        try {
            list = SoulKnifeDB.selectWhere("UserID = ? order by `ModifiDate`", user.getUserID()).setClass(LogicFileBean.class);
        } catch (BeanConfigErrorException e) {
            e.printStackTrace();
        }
        return list;
    }


    public List<LogicFileBean> listAllFile(String path, int offset, int length) throws SQLException {
        List<LogicFileBean> list = new ArrayList<>();
        try {
            List<LogicFileBean> files = SoulKnifeDB.selectWhere("UserID = ? and  LogicPath like ? LIMIT ?,?", user.getUserID(), path + "%", offset, length).setClass(LogicFileBean.class);
            list = list(files, path);
        } catch (BeanConfigErrorException e) {
            e.printStackTrace();
        }
        return list;
    }

    private List<LogicFileBean> list(List<LogicFileBean> files, String path) {
        // FIXME 一个文件夹下只有文件夹时不会显示
        if (path.equals("bin/"))
            return files;
        List<LogicFileBean> list = new LinkedList<>();
        HashSet<String> dir = new HashSet<>();
        for (LogicFileBean logicFile : files) {
            if (logicFile.getLogicPath().startsWith(path)) {
                String filepath = logicFile.getLogicPath().substring(path.length());
                if (filepath.contains("/")) {
                    String[] s = filepath.split("/");
                    if (s.length == 1) {
                        dir.add(logicFile.getLogicPath());
                    }
                } else {
                    list.add(logicFile);
                }
            }
        }
        for (String s : dir) {
            LogicFileBean tmp = new LogicFileBean();
            tmp.setLogicPath(s);
            list.add(tmp);
        }
        return new ArrayList<>(list);
    }

    public List<LogicFileBean> listAnyFile() throws SQLException {
        List<LogicFileBean> list = new ArrayList<>();
        try {
            list = SoulKnifeDB.selectWhere("UserID = ? ", user.getUserID()).setClass(LogicFileBean.class);
        } catch (BeanConfigErrorException e) {
            e.printStackTrace();
        }
        return list;
    }

    public List<LogicFileBean> searchFile(String key, String fileType) throws SQLException {
        List<LogicFileBean> list = new LinkedList<>();
        key = getRegular(key);
        for (LogicFileBean logicFile : listAnyFile()) {
            String type = FileTypePatternGenerator.getType(logicFile.getLogicFileName());
            boolean T = (fileType.equals(type) || fileType.equals("all"));
            if (Pattern.matches(key, logicFile.getLogicFileName()) && T) {
                list.add(logicFile);
            }
        }
        return new ArrayList<>(list);
    }

    public List<LogicFileBean> searchFile(String key, String fileType, int offset, int length) throws SQLException {
        Tuple<String, List<LogicFileBean>> tuple = cache.get(user);
        List<LogicFileBean> list;
        key = getRegular(key);
        if (tuple == null || !tuple.getFirst().equals(key)) {
            list = searchFile(key, fileType);
            tuple = new Tuple<>();
            tuple.setFirst(key);
            tuple.setSecond(list);
            cache.put(user, tuple);
        } else {
            list = tuple.getSecond();
        }
        int end = offset + length;
        if (end > list.size())
            end = list.size();
        return new ArrayList<>(list.subList(offset, end));
    }
}
